
#ifndef __RTMEMHEAP_HH__
#define __RTMEMHEAP_HH__


typedef int AoBool;
#define AO_FALSE  0
#define AO_TRUE 1
/* internal heap flags */
#define RT_MH_INTERNALMASK 0xF0000000u
#define RT_MH_FREEHEAPDESC 0x10000000u

typedef struct OSMemLink {
   struct OSMemLink* pnext;
   struct OSMemLink* pprev;
   struct OSMemLink* pnextRaw;  /* next RAW block                           */
   void*           pMemBlk;
   u8_t       blockType;   /* 1 = standard, 2 = raw (see RTMEM* flags) */
} OSMemLink;

/* MemLink blockTypes */
#define RTMEMSTD        0x0001
#define RTMEMRAW        0x0002
#define RTMEMMALLOC     0x0004
#define RTMEMSAVED      0x0008
#define RTMEMLINK       0x0010  /* contains MemLink */

/* ASN.1 memory allocation structures */

typedef struct OSMemHeap {
   OSMemLink*      phead;
   u32_t        usedUnits;
   u32_t        usedBlocks;
   u32_t        freeUnits;
   u32_t        freeBlocks;
   u32_t        keepFreeUnits;
   u32_t        defBlkSize;
   u32_t        refCnt;
   u32_t        flags;
} OSMemHeap;

#define RT_MH_DONTKEEPFREE 0x1

#define OSRTMH_PROPID_DEFBLKSIZE   1
#define OSRTMH_PROPID_SETFLAGS     2
#define OSRTMH_PROPID_CLEARFLAGS   3

#define OSRTMH_PROPID_USER         10



/* Alias for __cdecl modifier; if __cdecl keyword is not supported, 
 * redefine it as empty macro. */

#if !defined(OSCDECL)
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define OSCDECL __cdecl
#else
#define OSCDECL
#endif
#endif /* OSCDECL */

#ifdef __cplusplus
extern "C" {
#endif

//#define MEM_HEAP_DEBUG 1
/* Pointers to C Run-Time memory allocation functions *
 * (See memSetAllocFuncs)                           */


typedef void *(OSCDECL *OSReallocFunc) (void *ptr, size_t size);
typedef void  (OSCDECL *OSFreeFunc   ) (void *ptr);

#ifdef MEM_HEAP_DEBUG
typedef void *(OSCDECL *OSMallocFunc ) (size_t size,AoInt line, AoChar *filename);
#define memHeapCreate(x,y) _memHeapCreate(x,y,__FILE__,__LINE__)
#define memHeapRelease(x) _memHeapRelease(x,__FILE__,__LINE__)
#define memHeapAlloc(x,y) _memHeapAlloc(x,y,__FILE__,__LINE__)
int  _memHeapCreate (void** ppvMemHeap,int blkSize,char * file,int line);
void* _memHeapAlloc (void** ppvMemHeap, int nbytes,char * file,int line);
void _memHeapRelease (void ** ppvMemHeap,char * file,int line);
#else
typedef void *(OSCDECL *OSMallocFunc ) (size_t size);
int   memHeapCreate (void** ppvMemHeap,int blkSize);
void  memHeapRelease (void** ppvMemHeap);
void* memHeapAlloc (void** ppvMemHeap, int nbytes);
#endif

void  memHeapAddRef (void** ppvMemHeap);
void* memHeapAllocZ (void** ppvMemHeap, int nbytes);
int   memHeapCheckPtr (void** ppvMemHeap, void* mem_p);
void  memHeapFreeAll (void** ppvMemHeap);
void  memHeapFreePtr (void** ppvMemHeap, void* mem_p);
void* memHeapRealloc (void** ppvMemHeap, void* mem_p, int nbytes_);
void  memHeapReset (void** ppvMemHeap);

void* memHeapMarkSaved(void** ppvMemHeap, const void* mem_p, AoBool saved);

void  memHeapSetProperty(void** ppvMemHeap, u32_t propId, void* pProp);


/**
 * This function sets the pointers to standard allocation functions. These
 * functions are used to allocate/reallocate/free the memory blocks. By
 * default, standard C functions - 'malloc', 'realloc' and 'free' - are used.
 * But if some platforms do not support these functions (or some other reasons
 * exist) they can be overloaded. The functions being overloaded should have
 * the same prototypes as standard ones.
 *
 * @param malloc_func Pointer to the memory allocation function ('malloc' by
 *    default).
 * @param realloc_func Pointer to the memory reallocation function ('realloc'
 *    by default).
 * @param free_func Pointer to the memory deallocation function ('free' by
 *    default).
 */
void  memSetAllocFuncs (OSMallocFunc malloc_func,
                               OSReallocFunc realloc_func,
                               OSFreeFunc free_func);


#ifdef _STATIC_HEAP
void memSetStaticBuf (void* memHeapBuf, u32_t blkSize);
#endif
#define XM_K_MEMBLKSIZ  (4*1024)
#ifdef __cplusplus
}
#endif
#endif /* __RTMEMHEAP_HH__ */

